"""数据的预处理是数据分析，或者机器学习训练前的重要步骤。
通过数据预处理，可以

提高数据质量，处理数据的缺失值、异常值和重复值等问题，增加数据的准确性和可靠性
整合不同数据，数据的来源和结构可能多种多样，分析和训练前要整合成一个数据集
提高数据性能，对数据的值进行变换，规约等（比如无量纲化），让算法更加高效
本篇介绍的数据缩放处理，主要目的是消除数据的不同特征之间的量纲差异，使得每个特征的数值范围相同。这样可以避免某些特征对模型的影响过大，从而提高模型的性能。

1. 原理
数据缩放有多种方式，其中有一种按照最小值-最大值缩放的算法是最常用的。
其主要步骤如下：

计算数据列的最小值（min）和最大值（max）
对数据列中的每个值进行最小-最大缩放，即将其转换为 **[0,1]区间 **之内的一个值
缩放公式为：
new_data=data−min/max−min

实现缩放的代码如下："""

# 数据缩放的实现原理
from sklearn import preprocessing as pp
import numpy as np

data = np.array([10, 20, 30, 40, 50])
min_value = np.min(data)
max_value = np.max(data)

data_new = (data - min_value) / (max_value - min_value)

print("处理前: {}".format(data))
print("处理后: {}".format(data_new))
"""
# 运行结果
处理前: [10 20 30 40 50]
处理后: [0.   0.25 0.5  0.75 1.  ]
数值被缩放到 **[0,1]区间 **之内。
这个示例只是为了演示缩放的过程，实际场景中最好使用scikit-learn库中的函数。

scikit-learn中的minmax_scale函数是封装好的数据缩放函数。"""


data = np.array([10, 20, 30, 40, 50])
pp.minmax_scale(data, feature_range=(0, 1))
"""
# 运行结果
array([0.  , 0.25, 0.5 , 0.75, 1.  ])
使用scikit-learn中的minmax_scale函数得到的结果是一样的，数据也被压缩到 **[0,1]区间 **之内。
所以 数据缩放 的这个操作有时也被称为归一化。

不过，数据缩放不一定非得把数据压缩到 **[0,1]区间 **之内，
通过调整feature_range参数，可以把数据压缩到任意的区间。
"""
# 压缩到[0, 1]
print(pp.minmax_scale(data, feature_range=(0, 1)))

# 压缩到[-1, 1]
print(pp.minmax_scale(data, feature_range=(-1, 1)))

# 压缩到[0, 5]
print(pp.minmax_scale(data, feature_range=(0, 5)))

"""# 运行结果
[0.   0.25 0.5  0.75 1.  ]
[-1.  -0.5  0.   0.5  1. ]
[0.   1.25 2.5  3.75 5.  ]2. 作用
数据缩放的作用主要有：

2.1. 统一数据尺度
通过缩放处理，将不同量纲、不同尺度、不同单位的数据转换成一个统一的尺度，
避免由于数据量纲不一致而导致的数据分析结果失真或误导。

2.2. 增强数据可比性
通过缩放处理，将不同量纲、不同尺度、不同单位的数据转换成一个统一的尺度，使得不同数据之间的比较更加方便和有意义。
例如，在评价多个样本的性能时，如果采用不同的量纲、不同尺度、不同单位进行比较，会导致比较结果不准确甚至误导。
通过统一的缩放处理之后，可以消除这种影响，使得比较结果更加准确可信。

2.3. 增强数据稳定性
通过缩放处理，将数据的数值范围调整到一个相对较小的区间内，
增加数据的稳定性，避免由于数据分布范围过大或过小而导致的分析误差或计算误差。

2.4. 提高算法效率和精度
通过缩放处理，使得一些计算算法的效率和精度得到提高。
例如，在神经网络算法中，如果输入数据的尺度过大或过小，会导致算法训练时间过长或过短，同时也会影响算法的精度和稳定性。
而缩放处理之后，就可以使算法的训练时间和精度得到优化。

3. 总结
在scikit-learn库中，处理数据缩放不是只有上面的最小值-最大值缩放，
还可用StandardScaler进行标准化缩放；用RobustScaler实现尺度缩放和平移等等。

进行数据缩放时，需要注意一点，就是缩放处理对异常值非常敏感，
如果数据中存在极大或者极小的异常值时，有可能会破坏原始数据本身。
所以，缩放处理前，最好把异常值过滤掉。"""